﻿using System;
using System.Linq.Expressions;
using CoreEx.Database.Linq.Translators;
using CoreEx.Database.Query.Expressions;
using LinFu.IoC.Configuration;
using LinFu.IoC;
namespace CoreEx.Database.Linq.Implementation.Translators
{
    /// <summary>
    /// Handles expression tree nodes that represents method calls.
    /// </summary>
    [Implements(typeof(IExpressionTranslator_generic<MethodCallExpression>))]
    public class MethodCallExpressionTranslatorGeneric : ExpressionTranslatorGenericBase<MethodCallExpression>
    {

        /// <summary>
        /// Initializes a new instance of the <see cref="MethodCallExpressionTranslatorGeneric"/> class.
        /// </summary>
        /// <param name="translateResult">The <see cref="TranslateResult"/> that
        /// provides aggregated information about the current query translation process.</param>
        public MethodCallExpressionTranslatorGeneric(TranslateResult translateResult) : base(translateResult) { }

        /// <summary>
        /// Translates the <paramref name="expression"/> into a <see cref="DbExpression"/> instance.
        /// </summary>
        /// <param name="expression">The <see cref="Expression"/> to translate.</param>
        /// <returns><see cref="DbExpression"/></returns>
        /// <remarks>
        /// This method forwards the request to a <see cref="MethodCallExpressionTranslatorGeneric"/> implementation
        /// where the <see cref="ImplementsAttribute.ServiceName"/> equal to the method name.
        /// </remarks>
        public override DbExpression Translate(MethodCallExpression expression)
        {
            try
            {
                var translator = 
                    ServiceContainer.GetService<IExpressionTranslator_generic<MethodCallExpression>>(expression.Method.Name, TranslateResult);
                return translator.Translate(expression);
            }
            catch (ServiceNotFoundException serviceNotFoundException)
            {                
                throw new NotSupportedException(string.Format("The method '{0}' is not supported",expression.Method.Name),serviceNotFoundException);
            }            
        }
    }
}
